﻿using Casamiel.Domain.Entity;
using System;
using System.Collections.Generic;
using System.Text;

using Smooth.IoC.UnitOfWork.Interfaces;
using Casamiel.Domain;
using Dapper;
using System.Threading.Tasks;
using System.Linq;
using System.Threading;
using System.Globalization;

namespace Casamiel.Infrastructure.Repositories
{
    /// <summary>
    /// Order base repository.
    /// </summary>
    public sealed class OrderBaseRepository : BaseRepository<OrderBaseEntity, int>, IOrderBaseRepository
    {
        public OrderBaseRepository(IDbFactory factory) : base(factory)
        {
        }

        public async Task<OrderBaseEntity> GetByOrderCodeAsync<TSession>(string orderCode, string mobile) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.Connection
                    .QuerySingleOrDefaultAsync<OrderBaseEntity>($"SELECT top 1 * FROM {Sql.Table<OrderBaseEntity>(session.SqlDialect)} where OrderCode=@orderCode and mobile=@mobile", new { orderCode, mobile })
                    .ConfigureAwait(false);
            }
        }

        public async Task<OrderBaseEntity> GetByOrderCodeAsync<TSession>(string orderCode) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.Connection.QuerySingleOrDefaultAsync<OrderBaseEntity>($"SELECT top 1 * FROM {Sql.Table<OrderBaseEntity>(session.SqlDialect)} where OrderCode=@orderCode", new { orderCode }).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="TSession"></typeparam>
        /// <param name="IcTradeNO"></param>
        /// <returns></returns>
        public async Task<OrderBaseEntity> GetByIcTradeNOAsync<TSession>(string IcTradeNO) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                return await session.Connection.QuerySingleOrDefaultAsync<OrderBaseEntity>($"SELECT top 1 * FROM {Sql.Table<OrderBaseEntity>(session.SqlDialect)} where IcTradeNO=@IcTradeNO", new { IcTradeNO }).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Gets the list async.
        /// </summary>
        /// <returns>The list async.</returns>
        /// <param name="n">N.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<List<OrderBaseEntity>> GetListAsync<TSession>(int n) where TSession : class, ISession
        {
			var LastUpdateTime = DateTime.Now.AddMinutes(n).ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.CurrentCulture);

			string sql = $"select top 500 t.* from order_Base t where t.OrderStatus =1 and  t.LastUpdateTime <@LastUpdateTime ";//---and (CONVERT(varchar(100), o.TakeTime, 2) >= CONVERT(varchar(100), getdate(), 2))";
            //sql += "union select t.* from order_Base t inner join order_take o  on t.OrderBaseId = o.OrderBaseId where t.OrderStatus = 1 and CONVERT(varchar(100), dateadd(\"d\", -1, o.TakeTime), 2) = CONVERT(varchar(100), getdate(), 2) and(CONVERT(varchar(12), getdate(), 114) > '19:20:00:040')";

            using (var session = Factory.Create<TSession>())
            {
                var list = await session.QueryAsync<OrderBaseEntity>(sql,new { LastUpdateTime }).ConfigureAwait(false);
                return list.ToList();
            }
        }
        //public async Task<List<Order_BaseEntity>>GetList<TSession>() where TSession : class, ISession
        //{
        //    var sql = " select  ordercode from order_Base where   orderstatus =2  and source=2 and confrimReceiveTime <'2019-04-15'";
        //    using (var session = Factory.Create<TSession>())
        //    {
        //        var list = await session.Connection.QueryAsync<Order_BaseEntity>(sql);
        //        return list.ToList();
        //    }
        //}


        public async Task<List<OrderBaseEntity>> GetPayedOrderListAsync<TSession>(int source) where TSession : class, ISession
        {
            string sql = $"select  t.* from order_Base t where t.OrderStatus =2 and source=@source";//---and (CONVERT(varchar(100), o.TakeTime, 2) >= CONVERT(varchar(100), getdate(), 2))";

            using (var session = Factory.Create<TSession>())
            {
                var list = await session.QueryAsync<OrderBaseEntity>(sql, new { source }).ConfigureAwait(false);
                return list.ToList();
            }
        }

 
        //
        /// <summary>
        /// 更新订单状态及ResbillNO
        /// </summary>
        /// <returns>The status and res bill NOA sync.</returns>
        /// <param name="OrderBaseId">Order base identifier.</param>
        /// <param name="OrderStatus">Order status.</param>
        /// <param name="Resbillno">Resbillno.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task UpdateOrderStatusAndResBillNOAsync<TSession>(int OrderBaseId, int OrderStatus, string Resbillno) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                var sql = $"update  {Sql.Table<OrderBaseEntity>(session.SqlDialect)} set OrderStatus=@OrderStatus,ResBillNO=@Resbillno,LastUpdateTime=getdate() where OrderBaseId=@OrderBaseId";
				 
				await session.ExecuteAsync(sql.CheckSafeSql(), new { OrderStatus, Resbillno, OrderBaseId }).ConfigureAwait(false);
            }
        }

        /// <summary>
        /// Deletes the async.
        /// </summary>
        /// <returns>The async.</returns>
        /// <param name="OrderCode">Order code.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task DeleteAsync<TSession>(string OrderCode) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                var sql = $"delete from  {Sql.Table<OrderBaseEntity>(session.SqlDialect)}  where OrderCode=@OrderCode";
				 
				await session.ExecuteAsync(sql.CheckSafeSql(), new { OrderCode }).ConfigureAwait(false);
            }
        }

        /// <summary>
        /// Updates the order invoice URL by order code async.
        /// </summary>
        /// <returns>The order invoice URL by order code async.</returns>
        /// <param name="OrderCode">Order code.</param>
        /// <param name="InvoiceUrlcode">Invoice URL.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task UpdateOrderInvoiceUrlByOrderCodeAsync<TSession>(string OrderCode, string InvoiceUrlcode) where TSession : class, ISession
        {
            using (var session = Factory.Create<TSession>())
            {
                var sql = $"update  {Sql.Table<OrderBaseEntity>(session.SqlDialect)} set InvoiceUrl=@InvoiceUrlcode where OrderCode=@OrderCode";
				 
				await session.ExecuteAsync(sql.CheckSafeSql(), new { OrderCode, InvoiceUrlcode }).ConfigureAwait(false);
            }
        }

        /// <summary>
        /// 更新订单状态及ResbillNO
        /// </summary>
        /// <returns>The order status and res bill NOA sync.</returns>
        /// <param name="entity">原始数据</param>
        /// <param name="NewOrderStatus">新状态</param>
        /// <param name="Resbillno">Resbillno.</param>
        /// <param name="uow">Uow.</param>
        public async Task<bool> UpdateOrderStatusAndResBillNOAsync(OrderBaseEntity entity, int NewOrderStatus, string Resbillno, IUnitOfWork uow)
        {
			if (entity is null) {
				throw new ArgumentNullException(nameof(entity));
			}

			if (uow is null) {
				throw new ArgumentNullException(nameof(uow));
			}

			var sql = $"update  {Sql.Table<OrderBaseEntity>(uow.SqlDialect)} set OrderStatus=@NewOrderStatus,ResBillNO=@Resbillno,LastUpdateTime=getdate() where OrderBaseId=@OrderBaseId and OrderStatus=@OrderStatus";
			return await uow.Connection.ExecuteAsync(sql.CheckSafeSql(), new { NewOrderStatus, Resbillno, entity.OrderBaseId, entity.OrderStatus },uow.Transaction).ConfigureAwait(true) > 0;
        }
        /// <summary>
        /// Goodses the quantity async.
        /// </summary>
        /// <returns>The quantity async.</returns>
        /// <param name="pid">Pid.</param>
        /// <param name="dt">Dt.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task<int> GetGoodsQuantityByPidAsync<TSession>(int pid, DateTime dt) where TSession : class, ISession
        {
            string begin = dt.ToString("yyyy-MM-dd HH:mm:ss",CultureInfo.CurrentCulture);
            string end = DateTime.Now.ToString("yyyy-MM-dd 23:59:59", CultureInfo.CurrentCulture);
            var sql = "select ISNULL(sum(g.GoodsQuantity),0) from order_Base O inner join order_goods g on o.orderbaseid =g.orderbaseid where  o.createtime between @begin and @end  and g.goodsrelationid=@pid  and  o.orderstatus between 1 and 2 and  o.source=0";

			using (var session = Factory.Create<TSession>())
            {
                return await session.QuerySingleAsync<int>(sql, new { begin, end, pid }).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Updates the dada status async.
        /// </summary>
        /// <returns>The dada status async.</returns>
        /// <param name="OrderBaseId">Order base identifier.</param>
        /// <param name="DataStatus">Data status.</param>
        /// <typeparam name="TSession">The 1st type parameter.</typeparam>
        public async Task UpdateDadaStatusAsync<TSession>(int OrderBaseId, int DataStatus) where TSession : class, ISession
        {
            var sql = $"update order_dadaExpand set DadaStatus=@DataStatus where OrderbaseId=@OrderBaseId";
			using (var session = Factory.Create<TSession>())
            {
                await session.ExecuteAsync(sql.CheckSafeSql(), new { DataStatus, OrderBaseId }).ConfigureAwait(false);
            }
        }     
    }
}
